home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / digsby / videochat.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  12KB  |  291 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from __future__ import with_statement
  5. from functools import wraps
  6. from hashlib import md5
  7. from operator import attrgetter
  8. from digsby.web import DigsbyHttp, DigsbyHttpError
  9. from contacts.buddyinfo import BuddyInfo
  10. from common import profile, netcall
  11. from util import threaded, traceguard, Delegate
  12. import wx
  13. from logging import getLogger
  14. log = getLogger('videochat')
  15. INVITE_URL = 'http://v.digsby.com/?id=%(video_token)s&wid=%(widget_id)s'
  16. EMBED_TAG = '<object type="application/x-shockwave-flash" data="http://www.tokbox.com/f/%(widget_id)s" width="540" height="260"><param name="movie" value="http://www.tokbox.com/f/%(widget_id)s"></param><param name=FlashVars value="user=%(user_id)s&pass=%(md5password)s&meebo=true&onsite=false"></param></object>'
  17.  
  18. def tokbox_url(widget_id, user_id, md5password):
  19.     return 'http://www.tokbox.com/f/%s?user=%s&pass=%s&meebo=true&onsite=false' % (widget_id, user_id, md5password)
  20.  
  21. VIDEO_USERID_PREF = 'digsby.webvideo.user_id'
  22. VIDEO_WIDGETID_PREF = 'digsby.webvideo.widget_id'
  23.  
  24. def get_video_ids():
  25.     pref = pref
  26.     import common
  27.     user_id = pref(VIDEO_USERID_PREF, '', type = str)
  28.     widget_id = pref(VIDEO_WIDGETID_PREF, '', type = str)
  29.     if not user_id:
  30.         widget_id = ''
  31.     elif not widget_id:
  32.         user_id = ''
  33.     
  34.     return (user_id, widget_id)
  35.  
  36.  
  37. def save_video_ids(user_id, widget_id):
  38.     if not all((lambda .0: for a in .0:
  39. if isinstance(a, str):
  40. passa)((user_id, widget_id))):
  41.         raise TypeError('save_video_ids takes two non empty strings')
  42.     
  43.     profile.prefs[VIDEO_USERID_PREF] = user_id
  44.     profile.prefs[VIDEO_WIDGETID_PREF] = widget_id
  45.  
  46.  
  47. class VideoChat(object):
  48.     
  49.     def __init__(self, buddy):
  50.         self.buddy_info = BuddyInfo(buddy)
  51.         self.http = VideoChatHttp(profile.username, profile.password, *get_video_ids())
  52.         self._widget_jid = None
  53.         self._stopped = False
  54.         self.on_stop = Delegate()
  55.         self.handle_buddy_state(buddy)
  56.         my_alias = buddy.protocol.self_buddy.name
  57.         friend_alias = buddy.name
  58.         create = threaded(self.http.create_video)
  59.         create(my_alias, friend_alias, success = self.on_token, error = self.error_token)
  60.  
  61.     
  62.     def handle_buddy_state(self, buddy):
  63.         proto = buddy.protocol
  64.         
  65.         def on_protocol_state(proto, attr, old, new):
  66.             if not proto.connected:
  67.                 self.stop()
  68.             
  69.  
  70.         proto.add_observer(on_protocol_state, 'state', obj = self)
  71.         (self, self.on_stop) += (lambda : proto.remove_observer(on_protocol_state, 'state'))
  72.  
  73.     
  74.     def __repr__(self):
  75.         return '<VideoChat with %s>' % self.buddy_info
  76.  
  77.     
  78.     def on_token(self):
  79.         token = self.http.video_token
  80.         log.info('received video token: %s', token)
  81.         profile.connection.add_video_chat(token, self)
  82.         wx.CallAfter(self.on_url, self.http.invite_url(), self.http.embed())
  83.  
  84.     
  85.     def on_url(self, invite_url, embed_tag):
  86.         save_video_ids(self.http.user_id, self.http.widget_id)
  87.         buddy = self.buddy_info.buddy()
  88.         if buddy is not None:
  89.             message = _('Join me in an audio/video call: %s') % invite_url
  90.             
  91.             def send_and_echo_invite():
  92.                 convo = buddy.protocol.convo_for(buddy)
  93.                 convo._send_message(message)
  94.                 convo.system_message(_('You have invited %s to an audio/video chat.') % buddy.name)
  95.  
  96.             netcall(send_and_echo_invite)
  97.         
  98.         title = _('Audio/Video Call with %s' % self.buddy_info.buddy_name)
  99.         VideoChatWindow = VideoChatWindow
  100.         import gui.video.webvideo
  101.         frame = self.video_frame = VideoChatWindow(title, embed_tag, on_close = self.stop)
  102.         wx.CallAfter(frame.Show)
  103.  
  104.     
  105.     def error_token(self):
  106.         log.warning('error receiving token')
  107.         self.system_message(_('Audio/Video chat is currently unavailable.'))
  108.  
  109.     
  110.     def send_im(self, message):
  111.         convo = self.widget_convo
  112.         if convo is not None:
  113.             (None, netcall)((lambda : convo._send_message(message)))
  114.         
  115.  
  116.     
  117.     def widget_convo(self):
  118.         if self.widget_jid is None:
  119.             self.widget_jid = self.find_widget_jid()
  120.             if self.widget_jid is None:
  121.                 return log.warning('no widget jid, cannot forward message to widget')
  122.             
  123.         
  124.         conn = profile.connection
  125.         if not conn:
  126.             return log.warning('no Digsby connection, cannot forward message to widget')
  127.         
  128.         return conn.convo_for(self.widget_jid)
  129.  
  130.     widget_convo = property(widget_convo)
  131.     
  132.     def set_widget_jid(self, jid):
  133.         if jid != self._widget_jid:
  134.             self._widget_jid = jid
  135.             if profile.connection:
  136.                 profile.connection.get_buddy(jid).add_observer(self.buddy_status_change, 'status')
  137.             
  138.         
  139.  
  140.     widget_jid = property(attrgetter('_widget_jid'), set_widget_jid)
  141.     
  142.     def find_widget_jid(self):
  143.         conn = profile.connection
  144.         if conn is None:
  145.             return log.warning('cannot find widget jid: no digsby connection')
  146.         
  147.         resource = 'video.' + self.http.video_token
  148.         for buddict in conn.buddy_dictionaries():
  149.             for name, buddy in buddict.iteritems():
  150.                 if buddy.jid.domain == u'guest.digsby.org':
  151.                     for jid, res in buddy.resources.iteritems():
  152.                         if jid.resource == resource:
  153.                             return jid
  154.                             continue
  155.                     
  156.             
  157.         
  158.  
  159.     
  160.     def buddy_status_change(self, buddy, attr, old, new):
  161.         if buddy.online:
  162.             return None
  163.         
  164.         log.info('buddy %r went offline...stopping', buddy)
  165.         buddy.remove_observer(self.buddy_status_change, 'status')
  166.         if not self._stopped:
  167.             self.system_message(_('Audio/Video call ended by other party.'))
  168.         
  169.         self.stop()
  170.  
  171.     
  172.     def system_message(self, message):
  173.         traceguard.__enter__()
  174.         
  175.         try:
  176.             im_buddy = self.buddy_info.buddy()
  177.             if im_buddy is not None:
  178.                 convo = im_buddy.protocol.convo_for(im_buddy)
  179.                 convo.system_message(message)
  180.         finally:
  181.             pass
  182.  
  183.  
  184.     
  185.     def stop(self):
  186.         
  187.         self.stop = lambda *a: pass
  188.         self._stopped = True
  189.         log.info('stopping video chat %r', self)
  190.         if self.video_frame:
  191.             wx.CallAfter(self.video_frame.Destroy)
  192.         
  193.         convo = self.widget_convo
  194.         if convo is not None:
  195.             netcall(self.widget_convo.buddy.appear_offline_to)
  196.         
  197.         token = self.http.video_token
  198.         if token is not None:
  199.             conn = profile.connection
  200.             if conn is not None:
  201.                 conn.remove_video_chat(token)
  202.             
  203.         
  204.         threaded(self.http.close_video)()
  205.         self.on_stop()
  206.  
  207.  
  208.  
  209. def require_registered(func):
  210.     
  211.     def wrapper(self, *a, **k):
  212.         if not self.registered:
  213.             log.info('Not registered yet, requesting video user id...')
  214.             self.register()
  215.         
  216.         return func(self, *a, **k)
  217.  
  218.     wrapper = (wraps(func),)(wrapper)
  219.     return wrapper
  220.  
  221.  
  222. def password_hash(p):
  223.     for x in xrange(3):
  224.         p = md5(p).hexdigest()
  225.     
  226.     return p
  227.  
  228.  
  229. class VideoChatException(Exception):
  230.     pass
  231.  
  232.  
  233. class VideoChatNotRegistered(VideoChatException):
  234.     pass
  235.  
  236.  
  237. class VideoChatHttp(DigsbyHttp):
  238.     
  239.     def __init__(self, username, password, user_id = None, widget_id = None):
  240.         DigsbyHttp.__init__(self, username, password)
  241.         self.user_id = user_id
  242.         self.widget_id = widget_id
  243.  
  244.     
  245.     def registered(self):
  246.         if self.widget_id:
  247.             pass
  248.         return self.user_id
  249.  
  250.     registered = property(registered)
  251.     
  252.     def register(self):
  253.         resp = self.GET(obj = 'tokbox', act = 'register')
  254.         
  255.         try:
  256.             (self.user_id, self.widget_id) = resp.split(':')
  257.         except ValueError:
  258.             raise DigsbyHttpError('register expected "widget_id:user_id", but received %r' % resp)
  259.  
  260.         log.info('registered (user_id=%r, widget_id=%r)' % (self.user_id, self.widget_id))
  261.  
  262.     
  263.     def create_video(self, nick, guest):
  264.         self.video_token = self.GET(obj = 'widget', act = 'video', wid = self.widget_id, nick = nick.encode('utf-8'), guest = guest.encode('utf-8'))
  265.  
  266.     create_video = require_registered(create_video)
  267.     
  268.     def invite_url(self):
  269.         if self.video_token is None:
  270.             raise VideoChatException('no AV page has been created')
  271.         
  272.         return INVITE_URL % dict(video_token = self.video_token, widget_id = self.widget_id)
  273.  
  274.     invite_url = require_registered(invite_url)
  275.     
  276.     def embed(self):
  277.         return EMBED_TAG % dict(widget_id = self.widget_id, user_id = self.user_id, md5password = password_hash('digsby' + self.username))
  278.  
  279.     embed = require_registered(embed)
  280.     
  281.     def flash_url(self):
  282.         return tokbox_url(self.widget_id, self.user_id, password_hash('digsby' + self.username))
  283.  
  284.     flash_url = require_registered(flash_url)
  285.     
  286.     def close_video(self):
  287.         log.info('%r.close_video()', self)
  288.         self.GET(obj = 'widget', act = 'killvideo')
  289.  
  290.  
  291.